package com.code2roc.fastboot.system.org.bizlogic;

import com.code2roc.fastboot.system.org.model.SystemRoleDO;
import com.code2roc.fastboot.system.org.model.SystemRoleSettingDO;
import com.code2roc.fastboot.system.org.model.UserRoleModel;
import com.code2roc.fastboot.system.org.service.ISystemRoleService;
import com.code2roc.fastboot.system.org.service.ISystemRoleSettingService;
import com.code2roc.fastboot.system.setting.service.ISystemMenuSettingService;
import com.code2roc.fastboot.model.BaseBootLogic;
import com.code2roc.fastboot.util.BootUtil;
import com.code2roc.fastboot.framework.util.CommonUtil;
import com.code2roc.fastboot.framework.util.FileUtil;
import com.code2roc.fastboot.framework.util.LogUtil;
import com.code2roc.fastboot.framework.util.StringUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

@Component
public class RoleLogic extends BaseBootLogic {
    @Autowired
    private ISystemRoleService service;
    @Autowired
    private ISystemRoleSettingService roleSettingService;
    @Autowired
    private ISystemMenuSettingService menuSettingService;

    public void insert(SystemRoleDO entity){
        service.insert(entity);
    }

    public void delete(String row_id){
        service.delete(row_id);
        menuSettingService.deleteSettingBySettingID(row_id);
        roleSettingService.deleteByRoleID(row_id);
        authUtil.refreshTokenInfo();
    }

    public void update(SystemRoleDO entity){
        service.update(entity);
        authUtil.refreshTokenInfo();
    }

    public SystemRoleDO detail(String row_id){
        return service.selectOne(row_id);
    }

    public void updateRelation(String user_id,String role_id,boolean regist){
        roleSettingService.delete(user_id,role_id);
        if(regist){
            SystemRoleSettingDO settingDO = new SystemRoleSettingDO();
            settingDO.setUser_id(user_id);
            settingDO.setRole_id(role_id);
            roleSettingService.insert(settingDO);
        }
        authUtil.refreshTokenInfo();
    }

    public void updateUserRelation(UserRoleModel userRoleModel){
        roleSettingService.deleteByUserID(userRoleModel.getUser_id());
        for (UserRoleModel.RoleModel roleModel:userRoleModel.getRoleModelList()) {
            if(roleModel.isRegist()){
                SystemRoleSettingDO settingDO = new SystemRoleSettingDO();
                settingDO.setUser_id(userRoleModel.getUser_id());
                settingDO.setRole_id(roleModel.getRole_id());
                roleSettingService.insert(settingDO);
            }
        }
        authUtil.refreshTokenInfo();
    }

    public String exportData() {
        String fileid = "";
        try {
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            Calendar calendar = Calendar.getInstance();
            String dateName = df.format(calendar.getTime());
            fileid = "RoleExport_" + dateName + CommonUtil.getNewGuid();
            String filename = fileid + ".xml";
            String filefullpath = "tempfiles/export/" + filename;
            FileUtil.initfloderPath("tempfiles/export/");
            Document doc = DocumentHelper.createDocument();
            Element root = doc.addElement("orgfile");
            Element filetype = root.addElement("filetype");
            filetype.setText("role");

            Element rolelist = root.addElement("rolelist");
            List<SystemRoleDO> roleDOList = service.selectAllList();
            for (SystemRoleDO roleDO : roleDOList) {
                Element role = rolelist.addElement("role");
                for (Field field : roleDO.getClass().getDeclaredFields()) {
                    if (!Modifier.isStatic(field.getModifiers())) {
                        field.setAccessible(true);
                        Element tablefield = role.addElement(field.getName());
                        tablefield.setText(String.valueOf(field.get(roleDO)));
                    }
                }
            }

            Element rolesettinglist = root.addElement("rolesettinglist");
            List<SystemRoleSettingDO> roleSettingDOList = roleSettingService.selectAllList();
            for (SystemRoleSettingDO settingDO : roleSettingDOList) {
                Element rolesetting = rolesettinglist.addElement("rolesetting");
                for (Field field : settingDO.getClass().getDeclaredFields()) {
                    if (!Modifier.isStatic(field.getModifiers())) {
                        field.setAccessible(true);
                        Element tablefield = rolesetting.addElement(field.getName());
                        tablefield.setText(String.valueOf(field.get(settingDO)));
                    }
                }
            }

            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("utf-8");
            FileOutputStream out;
            out = new FileOutputStream(filefullpath);
            XMLWriter writer = new XMLWriter(out, format);
            writer.write(doc);
            writer.close();

            StringBuilder builder = new StringBuilder();
            builder.append("导出角色信息成功！" + CommonUtil.getNewLine());
            LogUtil.writeLog("org/role", "log", builder.toString());
        } catch (Exception e) {
            e.printStackTrace();
            StringBuilder builder = new StringBuilder();
            builder.append("导出角色信息失败！" + CommonUtil.getNewLine());
            builder.append("失败异常信息:" + CommonUtil.getNewLine());
            builder.append(e.getMessage() + CommonUtil.getNewLine());
            builder.append("失败堆栈信息:" + CommonUtil.getNewLine());
            builder.append(e.getStackTrace());
            LogUtil.writeLog("org/role", "log", builder.toString());
        }
        return fileid;
    }

    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.READ_UNCOMMITTED)
    public String importData(InputStream stream) {
        String errormsg = "";
        Exception exception = null;
        try {
            //解析xml
            SAXReader reader = new SAXReader();
            Document document = reader.read(stream);
            Element root = document.getRootElement();
            Element filetype = root.element("filetype");
            if (filetype != null && filetype.getText().equals("role")) {

                List<Element> rolelist = root.element("rolelist").elements("role");
                service.deleteAll();;
                for (Element role : rolelist) {
                    SystemRoleDO roleDO = new SystemRoleDO();
                    for (Field field : roleDO.getClass().getDeclaredFields()) {
                        if (!Modifier.isStatic(field.getModifiers())) {
                            field.setAccessible(true);
                            Element filednode = role.element(field.getName());
                            field.set(roleDO, BootUtil.convetXmlContent2FieldContent(filednode.getText(), field.getType()));
                        }
                    }
                    insert(roleDO);
                }

                List<Element> rolesettinglist = root.element("rolesettinglist").elements("rolesetting");
                roleSettingService.deleteAll();
                for (Element rolesetting : rolesettinglist) {
                    SystemRoleSettingDO settingDO = new SystemRoleSettingDO();
                    for (Field field : settingDO.getClass().getDeclaredFields()) {
                        if (!Modifier.isStatic(field.getModifiers())) {
                            field.setAccessible(true);
                            Element filednode = rolesetting.element(field.getName());
                            field.set(settingDO, BootUtil.convetXmlContent2FieldContent(filednode.getText(), field.getType()));
                        }
                    }
                    roleSettingService.insert(settingDO);
                }
            } else {
                errormsg = "导入文件不是人员文件！";
            }
        } catch (Exception e) {
            exception = e;
            errormsg = "导入失败";
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        } finally {
            StringBuilder builder = new StringBuilder();
            if (StringUtil.isEmpty(errormsg)) {
                builder.append("导入人员成功！" + CommonUtil.getNewLine());
            } else {
                builder.append("导入人员失败！" + CommonUtil.getNewLine());
            }
            if (!StringUtil.isEmpty(errormsg)) {
                if (errormsg.equals("导入失败")) {
                    builder.append("失败异常信息:" + CommonUtil.getNewLine());
                    builder.append(exception.getMessage() + CommonUtil.getNewLine());
                    builder.append("失败堆栈信息:" + CommonUtil.getNewLine());
                    builder.append(exception.getStackTrace());
                } else {
                    builder.append("导入失败信息:" + errormsg + CommonUtil.getNewLine());
                }
            }
            LogUtil.writeLog("org/user", "log", builder.toString());
        }
        return errormsg;
    }
}
